# -*- coding: utf-8 -*-

# graphic-pppoe-client - Easy graphic networking manager
#
# Author: GoTLiuM InSPiRiT <gotlium@gmail.com>
#
# Copyright 2010, GoTLiuM InSPiRiT <gotlium@gmail.com>.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2, as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranties of
# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.

from fs import putFile, fileExists, getFile
from os import listdir, system
from re import match, findall
from netinfo import *
from subprocess import call, Popen, PIPE, STDOUT

IFCONFIG = '/sbin/ifconfig'
DHCLIENT = '/sbin/dhclient'
RESOLVCONF = '/etc/resolv.conf'
ROUTE = '/sbin/route'

'''
https://github.com/ico2/pynetinfo/ - netinfo git repository
'''

def isMac(mac):
    return match("[0-9a-f]{2}([-:][0-9a-f]{2}){5}$", mac.lower())

def isIp(ip):
	segments = ip.split('.')
	if len(segments) != 4: return False
	for segment in segments:
		if not segment.isdigit() or int(segment) > 255 or len(segment) > 3:
			return False;
	return True;

def setIfState(ifName, state):
	try: set_state(ifName, state)
	except: return False
	return True

def getIfState(ifName):
	if ifName and fileExists('/sys/class/net/%s/carrier' % ifName):
		try: return int(open('/sys/class/net/%s/carrier' % ifName).read(1))
		except: pass
	return 0

def getAvailableIfaces(req_type = 'all'):
	if_arp = {
		'loop': 772,  # Loopback iface
		'eth': 1,     # Wired connection
		'wan': 1,     # Wi-Fi
		'ppp': 512,   # PPPoE
		'vpn': 65534, # Cisco VPN or OpenVPN
	}
	ifaces = []
	type = ""
	if req_type in if_arp.keys(): type = if_arp[req_type]
	for ifName in listdir('/sys/class/net/'):
		if fileExists('/sys/class/net/%s/type' % ifName):
			if req_type == 'all' or int(open('/sys/class/net/%s/type' % ifName).read()) == type:
				if req_type == 'wan' and fileExists('/proc/net/wireless'):
					if findall('%s:' % ifName, getFile('/proc/net/wireless')):
						ifaces.append(ifName)
				else:
					ifaces.append(ifName)
	if len(ifaces) > 0: return ifaces
	return None

def getActiveIfaces():
	return list_active_devs()

def getInactiveIfaces():
	allIfs = list_devs()
	actIfs = list_active_devs()
	if allIfs and actIfs:
		return list(set(allIfs)-set(actIfs))
	elif not actIfs and allIfs:
		return allIfs
	else: return None

def getIfStats(ifName):
	dir = '/sys/class/net/%s/statistics/' % ifName
	return (
		int(getFile(dir + 'rx_bytes').strip()),
		int(getFile(dir + 'tx_bytes').strip())
	)

def getIfInfo(ifName):
	if ifName and fileExists('/sys/class/net/%s/' % ifName):
		stats = getIfStats(ifName)
		if stats is not None:
			ifconfig = {
				'inet_addr': get_ip(ifName),
				'mask': get_netmask(ifName),
				'bcast': get_broadcast(ifName),
				'hwaddr': get_hwaddr(ifName),
				'input': stats[0],
				'output': stats[1]
			}
			return ifconfig
	return None

def getIfRoutes(ifName):
	routes = []
	allRoutes = get_routes()
	if allRoutes:
		for route in allRoutes:
			if 'dev' in route.keys() and ifName == route['dev']:
				routes.append(route)
	return routes

def addRoute(dev, dest, gateway = '', netmask='255.255.255.0'):
	try:
		add_route(dev, dest, gateway, netmask)
		return True
	except: return False

def delDefaultRoute():
	if system('%s del default' % ROUTE) != 0:
		return False
	return True

def delRoute(dev, dest, gateway = '', netmask = '255.255.255.0'):
	try:
		del_route(dev, dest, gateway, netmask)
		return True
	except: return False

def setIfConfig(ifName, ips, bcast = None, mac = None, mtu = None):
	try:
		if not isinstance(ips, list):
			return False

		iface = ifName
		for i, data in enumerate(ips):
			if i > 0: iface = '%s:%s' % (ifName, i - 1);
			ip, mask, gateway = data
			set_ip(iface, ip)
			if mask: set_netmask(iface, mask)
			if gateway and i == 0: add_route(iface, '0.0.0.0', gateway, '0.0.0.0')

		if bcast: set_broadcast(ifName, bcast)
		if mac and system('%s %s hw ether %s' % (IFCONFIG, ifName, mac)) != 0: return False
		if mtu and system('%s %s mtu %s' % (IFCONFIG, ifName, str(mtu))) != 0: return False
		return True
	except: return False

def setupDhcp(ifName):
	if system('%s %s' % (DHCLIENT, ifName)) != 0:
		return False
	return True

def addDnsConfig(dnsList):
	sdns = ''
	if len(dnsList) > 0:
		for dns in dnsList[0].split(" "):
			if isIp(dns): sdns += 'nameserver %s\n' % dns
	if len(dnsList) > 1:
		for name in dnsList[1].split(" "):
			if name: sdns += 'search %s\n' % name
	if putFile(RESOLVCONF, sdns):
		return True
	return False

def delDnsConfig():
	if putFile(RESOLVCONF, ""):
		return True
	return False

def getDns():
	try:
		shell = "cat /etc/resolv.conf |grep nameserver |awk '{ print $2 }'"
		p = Popen([shell], shell=True, stdout=PIPE, close_fds=True)
		p.wait()
		return p.stdout.read().splitlines()
	except: pass
	return None

def ping(ip):
	try:
		if call(["ping", "-c1", ip], stdout=open('/dev/null', 'w'), \
			stderr=STDOUT) == 0:
			return True
	except: pass
	return False

# Exmaples:
#print setIfState('eth0', 0);
#print getIfState('wlan0')
#print getAvailableIfaces()
#print getActiveIfaces()
#print getInactiveIfaces()
#print getIfStats('wlan0')
#print getIfInfo('wlan0')
#print getIfRoutes('wlan0')
#print addRoute('wlan0', '192.168.253.0', '192.168.253.1')
#print delRoute('wlan0', '192.168.253.0', '192.168.253.1')
#print isIp('192.168.1.1')
#print isMac('5c:ac:4c:7d:91:0d')
#print delDefaultRoute()
#print setIfConfig('eth0', [('192.168.253.6', '255.255.255.0', '192.168.253.1'), ('192.168.254.6', '255.255.255.0', '192.168.254.1')], mac='c8:0a:a9:f6:5b:1b')
#print setupDhcp('eth0')
#print addDnsConfig(['8.8.8.8 8.8.4.4', 'server'])
#print delDnsConfig()
#print getDns()
#print ping('192.168.253.1')
